/**
 * 循环覆盖文件
 * 张勇 41204@qq.com
 */

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdio.h>
#include <string.h>

#include "unios.h"
#include "rolling-file.h"


std_err_t roll_files(const char* filepath, int max_filecount) {
    if(!filepath || !strlen(filepath) || max_filecount < 2) { return STD_ERR_INVALID_ARG; }

    std_err_t err = STD_ERR_OK;
    char oldpath[512];
    char newpath[512];

    // 从后向前遍历所有文件
    for(int i = max_filecount - 1; i >= 0; i--) {
        // 生成老文件名
        if(i <= 0) {
            // 是第一个文件，文件名保持原样
            strcpy(oldpath, filepath);
        } else {
            // 不是第一个文件，则按顺序号生成文件名
            snprintf(oldpath, sizeof(oldpath), "%s.%d", filepath, i);
        }
        
        // 如果文件不存在，则继续向前
        if(!unios_file_exist(oldpath)) { continue; }

        // 文件存在
        if(i >= max_filecount - 1) {
            // 是最后一个文件，则直接删除它
            err = unios_file_delete(oldpath);
            if(err) { return STD_ERR_INVALID_STATE; }
            printf("Delete rolling file: '%s' !\n", oldpath);
        } else {
            // 把老文件名向后改为新文件名
            snprintf(newpath, sizeof(newpath), "%s.%d", filepath, i+1);
            err = unios_file_rename(oldpath, newpath);
            if(err) { return STD_ERR_INVALID_STATE; }
            printf("Rename rolling file: '%s' -> '%s' !\n", oldpath, newpath);
        }
    }

    return STD_ERR_OK;
}

std_err_t get_rolling_file(unios_file_t *fd, const char* filepath, int max_filesize, int max_filecount) {
    // 检查参数
    if(!fd || !filepath || !strlen(filepath) || max_filesize < 1 || max_filecount < 2) { return STD_ERR_INVALID_ARG; }
    std_err_t err = STD_ERR_OK;
    int64_t fsize = 0;

    // 看文件是否已经打开
    if(unios_file_is_valid(*fd)) {
        // 文件已经打开，则看文件是否还有空间
        fsize = unios_file_datasize(*fd);
        // 如果文件未超过最大尺寸，则直接返回当前文件
        if(fsize >= 0 && fsize < max_filesize) { return STD_ERR_OK; }
        // 文件无效，或文件已经超过最大尺寸，则关闭文件并尝试重新打开
        unios_file_destroy(fd);
    }

    // 查看文件是否存在以及大小
    fsize = unios_file_size(filepath);
    if(fsize < 0) {
        // 文件不存在，则以创建方式打开
    	err = unios_file_open(filepath, UNIOS_FILE_OFLAG_APPEND, fd);
        printf("Create rolling file: '%s' ...", filepath);
    } else if(fsize < max_filesize) {
        // 文件存在，但还小于最大尺寸，则以添加方式打开
    	err = unios_file_open(filepath, UNIOS_FILE_OFLAG_APPEND, fd);
        printf("Append rolling file: '%s' ...", filepath);
    } else {
        // 文件已经超过最大尺寸，则将文件名向后 rolling
        err = roll_files(filepath, max_filecount);
        if(err) { return err; }
        // 以创建方式打开
    	err = unios_file_open(filepath, UNIOS_FILE_OFLAG_APPEND, fd);
        printf("Create rolling file: '%s' ...", filepath);
    }

    if(err) { return STD_ERR_FAIL; }
    printf(" successfully.\n");
    return STD_ERR_OK;
}
